import style from './modal.less'
import '../icons/close.js'
import '../icons/info-fill.js'
import '../icons/check-circle-fill.js'
import '../icons/error-warning-fill.js'
import '../icons/question-fill.js'
import '../button/button.js'
import { getGlobalZIndex } from '../utils.js'

class AnModal extends HTMLElement {
    static get observedAttributes() {
        return [
            'open',
            'backdrop',
            'title',
            'closeable',
            'close-text',
            'ok-text',
            'update-zindex',
        ]
    }
    constructor(options) {
        super()
        if (options && typeof options === 'object') {
            // console.log(options)
            for (const key in options) {
                if (key === 'content') {
                    continue
                }
                if (options.hasOwnProperty.call(options, key)) {
                    const element = options[key]
                    this[key] = element
                }
            }
        }

        const shadowRoot = this.attachShadow({ mode: 'open' })
        const header = this.title
            ? `<div class="an-modal-header">${this.title}</div>`
            : ''
        let footer = []
        if (this.closeText) {
            footer.push(`<an-button class="an-modal-btn-close">${this.closeText}</an-button>`)
        }
        if (this.okText) {
            footer.push(`<an-button class="an-modal-btn-ok" type="primary">${this.okText}</an-button>`)
        }
        if (footer.length) {
            footer = `<div class="an-modal-footer">${footer.join('')}</div>`
        }
        const iconClose = this.closeable
            ? '<an-icon-close class="an-modal-close"></an-icon-close>'
            : ''
        const content = options?.content
        shadowRoot.innerHTML = `<style>
            ${style}
            :host{ --an-modal-zindex: ${getGlobalZIndex()} }
        </style>
        <div class="an-modal-backdrop"></div>
        <div class="an-modal">
            <div class="an-modal-wrapper" >
                ${header}
                <div class="an-modal-body">
                    ${content || '<slot></slot>'}
                </div>
                ${footer}
                ${iconClose}
            </div>
        </div>`
    }

    connectedCallback() {
        this.bindEvent()
    }
    attributeChangedCallback(name, oldValue, newValue) {
        switch (name) {
            case 'open': {
                if (this.open) {
                    this.appendStyle(`:host{--an-modal-zindex:${getGlobalZIndex()}}`)
                } else {
                    // 
                }
                break
            }
            default:
                break
        }
    }
    bindEvent() {
        if (this.backdrop) {
            this.bind(
                this.qs('.an-modal-backdrop'),
                'click',
                this.closeCallback.bind(this)
            )
        }
        if (this.closeable) {
            this.bind(
                this.qs('.an-modal-close'),
                'click',
                this.closeCallback.bind(this)
            )
        }
        if (this.closeText) {
            this.bind(
                this.qs('.an-modal-btn-close'),
                'click',
                this.closeCallback.bind(this)
            )
        }
        if (this.okText) {
            this.bind(
                this.qs('.an-modal-btn-ok'),
                'click',
                this.okCallback.bind(this)
            )
        }
    }
    closeCallback() {
        this.open = false
        this.emit('close')
    }
    okCallback() {
        this.open = false
        this.emit('ok')
    }

    set open(value) {
        value === null || value === false
            ? this.removeAttribute('open')
            : this.setAttribute('open', '')
    }
    get open() { return this.getAttribute('open') !== null }

    set backdrop(value) {
        value === null || value === false
            ? this.removeAttribute('backdrop')
            : this.setAttribute('backdrop', '')
    }
    get backdrop() { return this.getAttribute('backdrop') !== null }

    set closeable(value) {
        value === null || value === false
            ? this.removeAttribute('closeable')
            : this.setAttribute('closeable', '')
    }
    get closeable() { return this.getAttribute('closeable') !== null }

    set title(value) { this.setAttribute('title', value) }
    get title() { return this.getAttribute('title') }

    set closeText(value) { this.setAttribute('close-text', value) }
    get closeText() { return this.getAttribute('close-text') }

    set okText(value) { this.setAttribute('ok-text', value) }
    get okText() { return this.getAttribute('ok-text') }

    appendStyle(style) {
        const el = document.createElement('style')
        el.innerHTML = style
        this.shadowRoot.append(el)
    }

    qs(name) {
        return this.shadowRoot.querySelector(name)
    }

    bind(el, eventName, eventHandler, options) {
        el.addEventListener(eventName, eventHandler, options)
    }
    unbind(el, eventName, eventHandler, options) {
        el.removeEventListener(eventName, eventHandler, options)
    }
    emit(eventName, customEventInit) {
        return this.dispatchEvent(new CustomEvent(eventName, customEventInit))
    }
}

if (!customElements.get('an-modal')) {
    customElements.define('an-modal', AnModal)
}

export const Modal = Object.create(null)

Modal.open = ({
    ok,
    close,
    unmount = true,
    ...options
} = {}) => {
    // console.log({ ok, close, unmount, ...options })
    const el = new AnModal(options)
    document.body.appendChild(el)
    el.open = true
    el.addEventListener('close', function () {
        if (typeof close === 'function') {
            close()
        }
        unmount && setTimeout(() => document.body.removeChild(el), 300)
    })

    el.addEventListener('ok', function () {
        if (typeof ok === 'function') {
            ok()
        }
        unmount && setTimeout(() => document.body.removeChild(el), 300)
    })
    return el
}

Modal.alert = (options) => {
    return Modal.open({
        ...options,
        okText: options.okText || '确定',
        content: `<div class="an-modal-message">
            <span class="an-modal-message-icon" style="color:var(--an-color-primary);">
                <an-icon-info-fill></an-icon-info-fill>
                </span>
                ${options.content}
                </div>`
    })
}

Modal.success = (options) => {
    return Modal.open({
        ...options,
        okText: options.okText || '确定',
        content: `<div class="an-modal-message">
            <span class="an-modal-message-icon" style="color:var(--an-color-success);">
                <an-icon-check-circle-fill></an-icon-check-circle-fill>
            </span>
            ${options.content}
        </div>`
    })
}


Modal.error = (options) => {
    return Modal.open({
        ...options,
        okText: options.okText || '确定',
        content: `<div class="an-modal-message">
            <span class="an-modal-message-icon" style="color:var(--an-color-danger);">
                <an-icon-error-warning-fill></an-icon-error-warning-fill>
            </span>
            ${options.content}
        </div>`
    })
}

Modal.confirm = (options) => {
    return Modal.open({
        ...options,
        closeText: options.closeText || '关闭',
        okText: options.okText || '确定',
        content: `<div class="an-modal-message">
            <span class="an-modal-message-icon" style="color:var(--an-color-warning);">
                <an-icon-question-fill></an-icon-question-fill>
            </span>
            ${options.content}
        </div>`
    })
}